//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using OpenLS.UI.Interop;
using OpenLS.UI.Themes;
using MahApps.Metro.Controls;

namespace OpenLS.UI
{
    public class RibbonWindow : Window
    {
        static RibbonWindow()

        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(RibbonWindow), new FrameworkPropertyMetadata(typeof(RibbonWindow)));
            EventManager.RegisterClassHandler(typeof(RibbonWindow), SizeChangedEvent, new SizeChangedEventHandler (onSizeChanged));
            
            
        }
        public RibbonWindow()
        {
            this.Style = (Style) new RibbonWindowResources()[typeof (RibbonWindow)];
            CommandBindings.Add(new CommandBinding(OfficeApplicationCommands.Exit, onExit, onCanExit));
            Background = Brushes.White;
        }
        void onExit(object sender, object args)
        {
            Close();
        }

        static void onCanExit(object sender, CanExecuteRoutedEventArgs args)
        {
            args.CanExecute = true;
            args.Handled = true;
        }
        static void onSizeChanged(object sender, SizeChangedEventArgs args)
        {
#if DEBUG
            RibbonWindow w = (RibbonWindow) sender;
            var ribbon = w.Ribbon;
            if (ribbon != null)
            {
                if (args.NewSize.Height > 280 && args.NewSize.Width > 300)
                    ribbon.Visibility = System.Windows.Visibility.Visible;
                else
                {
                    ribbon.Visibility = System.Windows.Visibility.Collapsed;
                }
            }

#endif
        }


        public FrameworkElement Ribbon
        {
            get { return (FrameworkElement)GetValue(RibbonProperty); }
            set { SetValue(RibbonProperty, value); }
        }

        /// <summary>
        /// Obsolete after August 2010, use Ribbon.ApplicationMenu instead
        /// </summary>
        // Using a DependencyProperty as the backing store for Ribbon.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RibbonProperty =
            DependencyProperty.Register("Ribbon", typeof(FrameworkElement), typeof(RibbonWindow), new UIPropertyMetadata(null));


        /// <summary>
        /// Obsolete after August 2010, use Ribbon.ApplicationMenu instead
        /// </summary>
        public ApplicationMenu ApplicationMenu
        {
            get { return (ApplicationMenu) GetValue(ApplicationMenuProperty); }
            set { SetValue(ApplicationMenuProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ApplicationMenu.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ApplicationMenuProperty =
            DependencyProperty.Register("ApplicationMenu", typeof(ApplicationMenu), typeof(RibbonWindow), new UIPropertyMetadata(null));



        public FrameworkElement QuickAccessToolbar
        {
            get { return (FrameworkElement)GetValue(QuickAccessToolbarProperty); }
            set { SetValue(QuickAccessToolbarProperty, value); }
        }

        // Using a DependencyProperty as the backing store for QuickAccessToolbar.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty QuickAccessToolbarProperty =
            DependencyProperty.Register("QuickAccessToolbar", typeof(FrameworkElement), typeof(RibbonWindow), new UIPropertyMetadata(null));


        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            if (IsGlass)
            {
                Processor = new VistaWindowMessageProcessor(this);
                ResizeAdorner = null;
                ResizeMode = ResizeMode.CanResizeWithGrip;
            }
            else
            {
                ResizeAdorner = new WindowResizeAdorner(getRootElement(), this);
                ResizeMode = ResizeMode.NoResize;
                Processor = new XpWindowMessageProcessor(this);
            }

            
        }


        #region win32
        internal void ToggleMaximized()
        {
            WindowState = (WindowState == WindowState.Maximized) ? WindowState.Normal : WindowState.Maximized;

        }



        public bool IsGlass
        {
            get { return (bool)GetValue(IsGlassProperty); }
            set { SetValue(IsGlassProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsGlass.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsGlassProperty =
            DependencyProperty.Register("IsGlass", typeof(bool), typeof(RibbonWindow), new UIPropertyMetadata(NativeMethods.IsCompositionEnabled(),
            onIsGlassChangedCb));

        static void onIsGlassChangedCb(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            RibbonWindow w = (RibbonWindow)d;
            w.onIsGlassChanged(e);
        }

        private void onIsGlassChanged(DependencyPropertyChangedEventArgs e)
        {
            IntPtr handle = (new WindowInteropHelper(this)).Handle;
            HwndSource src = HwndSource.FromHwnd(handle);
            //if (Processor != null)
           // {
             //   src.RemoveHook(Processor.WndProc);
            //}   
            bool b = (bool)e.NewValue;
            if (b)
            {
                Processor = new VistaWindowMessageProcessor(this);
                ResizeAdorner = null;
                ResizeMode = ResizeMode.CanResizeWithGrip;
            }
            else
            {
                ResizeAdorner = new WindowResizeAdorner(getRootElement(), this);
                ResizeMode = ResizeMode.NoResize;
                Processor = new XpWindowMessageProcessor(this);
            }
            ///src.AddHook(Processor.WndProc);


        }
        UIElement getRootElement()
        {
            Contract.Ensures(Contract.Result<UIElement>() != null);
            return (UIElement) Template.FindName("PART_MainGrid", this);
        }

        private WindowResizeAdorner _resizeAdorner;

        private WindowMessageProcessor _processor;

        internal double CaptionHeight
        {
            get
            {
                return SystemParameters.CaptionHeight + 8; //\\
            }
        }

        internal WindowResizeAdorner ResizeAdorner
        {
            get { return _resizeAdorner; }
            set { if (_resizeAdorner == value)
                return;
                if (value == null)
                {
                    AdornerLayer.GetAdornerLayer(getRootElement()).Remove(_resizeAdorner);
                }
                else
                {
                    var e = getRootElement();
                    var layer = AdornerLayer.GetAdornerLayer(e);
                    layer.Add(value);
                }
                _resizeAdorner = value; }
        }

        internal WindowMessageProcessor Processor
        {
            get { return _processor; }
            set
            {
                if (_processor == value)
                    return;
                IntPtr handle = (new WindowInteropHelper(this)).Handle;
                if (Processor != null)
                HwndSource.FromHwnd(handle).RemoveHook(Processor.WndProc);
                _processor = value;
                if (Processor != null)
                    HwndSource.FromHwnd(handle).AddHook(Processor.WndProc);
            }
        }

        #endregion


        internal void AdjustMargins()
        {
            NativeMethods.Margins pMargins = new NativeMethods.Margins();
            pMargins.Top = (int)CaptionHeight;
            IntPtr hwnd = (new WindowInteropHelper(this)).Handle;
            NativeMethods.DwmExtendFrameIntoClientArea(hwnd, ref pMargins);

        }
    }
}
